<template>
  <div class="gantt-chart" :class="{ 'fullscreen': isFullscreen }">
          <div class="gantt-header">
        <div class="task-list-header" :style="{ width: taskListWidth + 'px' }">任务列表</div>
        <div class="timeline-header">
          时间轴 ({{ timelineStart ? timelineStart.format('YYYY-MM-DD') : '' }} 至 {{ timelineEnd ? timelineEnd.format('YYYY-MM-DD') : '' }})
        </div>
        <div class="gantt-controls">
          <el-button 
            type="primary" 
            size="small" 
            @click="toggleFullscreen"
            :icon="isFullscreen ? 'el-icon-close' : 'el-icon-full-screen'"
          >
            {{ isFullscreen ? '退出全屏' : '全屏' }}
          </el-button>
          <el-button 
            type="success" 
            size="small" 
            @click="exportImage"
            :loading="isExporting"
            style="margin-left: 8px;"
          >
            {{ isExporting ? '导出中...' : '导出图片' }}
          </el-button>
        </div>
      </div>
    
    <div class="gantt-body">
      <TaskList
        :tasks="tasks"
        :columns="taskListColumns"
        :all-columns="allColumns"
        :width="taskListWidth"
        :collapsed-tasks="collapsedTasks"
        @scroll="handleTaskListScroll"
        @task-select="selectTask"
        @task-toggle="toggleTask"
        @sort-change="handleSortChange"
        @columns-change="handleColumnsChange"
      />
      
      <!-- 可拖拽的分隔条 -->
      <div 
        class="resize-handle-vertical"
        @mousedown="startResize"
        :class="{ 'resizing': isResizing }"
      ></div>
      
      <GanttTimeline
        :tasks="filteredTasks"
        :all-tasks="tasks"
        :timeline-start="timelineStart"
        :timeline-end="timelineEnd"
        :view-type="viewType"
        :zoom-level="zoomLevel"
        :show-today="showToday"
        :show-dependency-lines="showDependencyLines"
        :time-range="timeRange"
        :drag-state="dragState"
        :task-list-scroll-top="taskListScrollTop"
        @scroll="handleTimelineScroll"
        @task-select="selectTask"
        @task-drag-start="handleTaskDragStart"
        @task-drag-move="handleTaskDragMove"
        @task-drag-end="handleTaskDragEnd"
        @tooltip-show="handleTooltipShow"
        @tooltip-hide="handleTooltipHide"
      />
    </div>
  </div>
</template>

<script>
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import dayjs from 'dayjs'
import minMax from 'dayjs/plugin/minMax'
import isoWeek from 'dayjs/plugin/isoWeek'
import html2canvas from 'html2canvas'
import TaskList from './TaskList.vue'
import GanttTimeline from './GanttTimeline.vue'
dayjs.extend(minMax)
dayjs.extend(isoWeek)

export default {
  name: 'GanttChart',
  components: {
    TaskList,
    GanttTimeline
  },
  props: {
    tasks: {
      type: Array,
      required: true
    },
    taskListColumns: {
      type: Array,
      required: true,
      validator: (columns) => {
        return columns.every(col => 
          col.key && 
          col.label && 
          typeof col.width === 'number' &&
          typeof col.sortable === 'boolean'
        )
      }
    },
    // 新增：所有可用列定义
    allColumns: {
      type: Array,
      default: () => []
    },
    zoomLevel: {
      type: Number,
      default: 1
    },
    showToday: {
      type: Boolean,
      default: true
    },
    showDependencyLines: {
      type: Boolean,
      default: true
    },
    timeRange: {
      type: Array,
      default: null
    },
    viewType: {
      type: String,
      default: 'day', // 'day' | 'week'
      validator: (value) => ['day', 'week'].includes(value)
    }
  },
  emits: ['update-task', 'delete-task', 'edit-task', 'columns-change'],
  setup(props, { emit }) {
    const taskListRef = ref(null)
    const timelineAreaRef = ref(null)
    
    // 全屏状态
    const isFullscreen = ref(false)
    
    // 任务列表宽度状态
    const taskListWidth = ref(800)
    const isResizing = ref(false)
    
    // 导出状态
    const isExporting = ref(false)
    
    // 拖拽状态
    const dragState = ref({
      isDragging: false,
      dragType: null, // 'move' | 'resize-start' | 'resize-end'
      draggedTask: null,
      startX: 0,
      startY: 0,
      originalStartDate: null,
      originalEndDate: null,
      autoScrollInterval: null,
      tempEndDate: null, // 临时结束日期，用于resize-end拖拽
      tempStartDate: null // 临时开始日期，用于resize-start拖拽
    })
    
    // 悬浮提示状态
    const tooltip = ref({
      visible: false,
      task: null,
      style: {
        left: '0px',
        top: '0px'
      }
    })
    
    // 排序状态
    const sortField = ref('')
    const sortDirection = ref('asc')
    
    // 滚动同步状态
    const taskListScrollTop = ref(0)
    
    // 监听taskListColumns变化
    watch(() => props.taskListColumns, (newColumns) => {
      console.log('GanttChart - taskListColumns props 变化:', newColumns)
    }, { deep: true })
    
    // 计算时间轴
    const timelineStart = computed(() => {
      // 优先使用props传递的时间范围
      if (props.timeRange && props.timeRange.length >= 2) {
        return props.timeRange[0]
      }
      // 否则根据任务计算
      if (!props.tasks || props.tasks.length === 0) {
        return dayjs()
      }
      const allDates = props.tasks.flatMap(task => [task.startDate, task.endDate])
      return dayjs.min(allDates) || dayjs()
    })
    
    const timelineEnd = computed(() => {
      // 优先使用props传递的时间范围
      if (props.timeRange && props.timeRange.length >= 2) {
        return props.timeRange[1]
      }
      // 否则根据任务计算
      if (!props.tasks || props.tasks.length === 0) {
        return dayjs().add(30, 'days')
      }
      const allDates = props.tasks.flatMap(task => [task.startDate, task.endDate])
      return dayjs.max(allDates) || dayjs().add(30, 'days')
    })
    

    
    // 确保 viewType 的响应性
    const currentViewType = computed(() => props.viewType)
    

    
    const collapsedTasks = ref(new Set())
    
    // 计算任务的层级
    const getTaskLevel = (task) => {
      if (!task || !task.parentId) {
        return 0
      }
      
      let level = 0
      let currentTask = task
      
      // 递归计算层级
      while (currentTask.parentId) {
        level++
        currentTask = props.tasks.find(t => t.id === currentTask.parentId)
        if (!currentTask) {
          break
        }
      }
      
      return level
    }
    
    // 检查任务是否有子任务
    const hasChildren = (task) => {
      if (!props.tasks || props.tasks.length === 0) {
        return false
      }
      const children = props.tasks.filter(t => t.parentId === task.id)
      console.log(`任务 ${task.name} 的子任务:`, children.map(t => t.name))
      return children.length > 0
    }
    
    // 获取任务的子任务数量
    const getTaskChildrenCount = (taskId) => {
      if (!props.tasks || props.tasks.length === 0) {
        return 0
      }
      return props.tasks.filter(t => t.parentId === taskId).length
    }
    
    // 切换任务的展开/收缩状态
    const toggleTask = (taskId) => {
      if (collapsedTasks.value.has(taskId)) {
        collapsedTasks.value.delete(taskId)
      } else {
        collapsedTasks.value.add(taskId)
      }
    }
    

    

    

    

    
    // 任务条样式
    const getTaskBarStyle = (task) => {
      if (!task || !filteredTasks.value) {
        return {
          left: '0px',
          width: '10px',
          backgroundColor: '#909399'
        }
      }
      
      // 安全获取dayjs对象
      let startDate = getSafeDayjs(task.startDate)
      let endDate = getSafeDayjs(task.endDate)
      
      if (!startDate || !endDate) {
        return {
          left: '0px',
          width: '10px',
          backgroundColor: '#909399'
        }
      }
      
      // 如果是正在拖拽resize-start的任务，使用临时开始日期
      if (dragState.value.isDragging && 
          dragState.value.dragType === 'resize-start' && 
          dragState.value.draggedTask?.id === task.id &&
          dragState.value.tempStartDate) {
        startDate = dragState.value.tempStartDate
      }
      
      // 如果是正在拖拽resize-end的任务，使用临时结束日期
      if (dragState.value.isDragging && 
          dragState.value.dragType === 'resize-end' && 
          dragState.value.draggedTask?.id === task.id &&
          dragState.value.tempEndDate) {
        endDate = dragState.value.tempEndDate
      }
      
      let startOffset, duration
      if (currentViewType.value === 'week') {
        // 在周视图下，需要找到任务开始时间所在的周索引
        const weekIndex = timelineUnits.value.findIndex(week => 
          startDate.isSame(week.start, 'week') || 
          (startDate.isAfter(week.start) && startDate.isBefore(week.end)) ||
          startDate.isSame(week.start, 'day') ||
          startDate.isSame(week.end, 'day')
        )
        
        // 计算任务持续时间（跨越的周数）
        const endWeekIndex = timelineUnits.value.findIndex(week => 
          endDate.isSame(week.start, 'week') || 
          (endDate.isAfter(week.start) && endDate.isBefore(week.end)) ||
          endDate.isSame(week.start, 'day') ||
          endDate.isSame(week.end, 'day')
        )
        
        startOffset = weekIndex >= 0 ? weekIndex : 0
        duration = endWeekIndex >= 0 ? (endWeekIndex - weekIndex + 1) : 1
      } else {
        startOffset = startDate.diff(timelineStart.value, 'days')
        duration = endDate.diff(startDate, 'days') + 1
      }
      
              const taskIndex = filteredTasks.value.findIndex(t => t.id === task.id)
        
        const position = {
          left: Math.max(0, startOffset * unitWidth.value),
          width: Math.max(10, duration * unitWidth.value),
          top: taskIndex * 50 + 10
        }
      
      // 减去resize按钮的延伸空间（左右各5px，总共10px）
      const adjustedWidth = position.width - 10
      return {
        left: position.left + 'px',
        width: adjustedWidth + 'px',
        backgroundColor: getTaskColor(task)
      }
    }

    // 获取任务颜色
    const getTaskColor = (task) => {
      if (task.color) return task.color
      
      // 根据状态设置默认颜色
      switch (task.status) {
        case 'completed':
          return '#67C23A'
        case 'in-progress':
          return '#409EFF'
        case 'pending':
          return '#E6A23C'
        case 'cancelled':
          return '#F56C6C'
        default:
          return '#909399'
      }
    }
    

    
    // 安全获取dayjs对象
    const getSafeDayjs = (date) => {
      if (!date) return null
      try {
        // 如果已经是dayjs对象
        if (date.format && typeof date.format === 'function' && date.diff && typeof date.diff === 'function') {
          return date
        }
        // 如果是字符串或其他格式，尝试转换为dayjs
        const dayjsDate = dayjs(date)
        if (dayjsDate.isValid()) {
          return dayjsDate
        }
        return null
      } catch (error) {
        console.warn('日期转换失败:', error, date)
        return null
      }
    }
    
    // 安全格式化日期
    const getFormattedDate = (date) => {
      const dayjsDate = getSafeDayjs(date)
      if (!dayjsDate) return '--'
      return dayjsDate.format('MM-DD')
    }
    
    // 滚动同步
    const handleTaskListScroll = (event) => {
      // 更新滚动位置状态
      taskListScrollTop.value = event.target.scrollTop
    }
    
    const handleTimelineScroll = (e) => {
      // 处理时间线的滚动事件
      // 这里可以处理水平滚动或其他逻辑
      console.log('时间轴滚动:', e.target.scrollLeft, e.target.scrollTop)
    }
    
    // 任务选择
    const selectTask = (task) => {
      emit('edit-task', task)
    }
    
    // 显示悬浮提示
    const showTooltip = (event, task) => {
      if (!task) return
      
      const rect = timelineAreaRef.value.getBoundingClientRect()
      const scrollLeft = timelineAreaRef.value.scrollLeft || 0
      const scrollTop = timelineAreaRef.value.scrollTop || 0
      
      // 计算提示框位置
      let left = event.clientX - rect.left + scrollLeft + 10
      let top = event.clientY - rect.top + scrollTop - 10
      
      // 确保提示框不超出视窗边界
      const tooltipWidth = 280
      const tooltipHeight = 200
      
      if (left + tooltipWidth > rect.width + scrollLeft) {
        left = event.clientX - rect.left + scrollLeft - tooltipWidth - 10
      }
      
      if (top + tooltipHeight > rect.height + scrollTop) {
        top = event.clientY - rect.top + scrollTop - tooltipHeight - 10
      }
      
      tooltip.value = {
        visible: true,
        task: task,
        style: {
          left: left + 'px',
          top: top + 'px'
        }
      }
    }
    
    // 隐藏悬浮提示
    const hideTooltip = () => {
      tooltip.value.visible = false
      tooltip.value.task = null
    }
    
    // 处理时间线组件的事件
    const handleTaskDragStart = (data) => {
      // 更新拖拽状态
      dragState.value = data.dragState || {
        isDragging: true,
        dragType: data.type,
        draggedTask: data.task,
        startX: data.startX,
        startY: data.startY,
        originalStartDate: data.originalStartDate,
        originalEndDate: data.originalEndDate,
        autoScrollInterval: null,
        tempEndDate: null,
        tempStartDate: null
      }
    }
    
    const handleTaskDragMove = (data) => {
      if (data.autoScrollInterval) {
        dragState.value.autoScrollInterval = data.autoScrollInterval
      }
      
      // 如果是任务更新事件
      if (data.taskId && data.updates) {
        emit('update-task', data.taskId, data.updates)
      }
    }
    
    const handleTaskDragEnd = (data) => {
      // 如果是任务更新事件
      if (data.taskId && data.updates) {
        emit('update-task', data.taskId, data.updates)
      }
      
      // 重置拖拽状态
      if (data.dragState) {
        dragState.value = data.dragState
      } else {
        dragState.value = {
          isDragging: false,
          dragType: null,
          draggedTask: null,
          startX: 0,
          startY: 0,
          originalStartDate: null,
          originalEndDate: null,
          autoScrollInterval: null,
          tempEndDate: null,
          tempStartDate: null
        }
      }
    }
    
    const handleTooltipShow = (data) => {
      // 转发提示框显示事件
      tooltip.value = {
        visible: true,
        task: data.task,
        style: data.style
      }
    }
    
    const handleTooltipHide = () => {
      // 转发提示框隐藏事件
      hideTooltip()
    }
    
    // 组件卸载时清理
    onMounted(() => {
      return () => {
        if (dragState.value.autoScrollInterval) {
          clearInterval(dragState.value.autoScrollInterval)
        }
        document.removeEventListener('mousemove', handleDragMove)
        document.removeEventListener('mouseup', handleDragEnd)
      }
    })
    
    // 监听 viewType 变化，确保重新计算
    watch(() => props.viewType, () => {
      // 强制重新计算 timelineUnits
      nextTick(() => {
        // 重新计算完成
      })
    })
    
    // 全屏切换函数
    const toggleFullscreen = () => {
      isFullscreen.value = !isFullscreen.value
      
      // 延迟执行，确保DOM更新完成
      nextTick(() => {
        if (isFullscreen.value) {
          // 进入全屏时，调整任务列表宽度和滚动位置
          taskListWidth.value = 1000
          if (timelineAreaRef.value) {
            timelineAreaRef.value.scrollLeft = 0
          }
          if (taskListRef.value) {
            taskListRef.value.scrollTop = 0
          }
        } else {
          // 退出全屏时，恢复默认宽度
          taskListWidth.value = 800
        }
      })
    }
    
    // 开始拖拽调整宽度
    const startResize = (e) => {
      e.preventDefault()
      e.stopPropagation()
      
      isResizing.value = true
      const startX = e.clientX
      const startWidth = taskListWidth.value
      
      const handleMouseMove = (e) => {
        const deltaX = e.clientX - startX
        const newWidth = Math.max(400, Math.min(1200, startWidth + deltaX)) // 最小400px，最大1200px
        taskListWidth.value = newWidth
      }
      
      const handleMouseUp = () => {
        isResizing.value = false
        document.removeEventListener('mousemove', handleMouseMove)
        document.removeEventListener('mouseup', handleMouseUp)
        document.body.style.cursor = ''
        document.body.style.userSelect = ''
      }
      
      document.addEventListener('mousemove', handleMouseMove)
      document.addEventListener('mouseup', handleMouseUp)
      document.body.style.cursor = 'col-resize'
      document.body.style.userSelect = 'none'
    }
    
    // 导出图片函数
    const exportImage = async () => {
      if (isExporting.value) return
      
      isExporting.value = true
      
      try {
        // 获取甘特图容器
        const ganttContainer = document.querySelector('.gantt-chart')
        if (!ganttContainer) {
          throw new Error('找不到甘特图容器')
        }
        
        // 保存原始样式和状态
        const originalStyles = {
          overflow: ganttContainer.style.overflow,
          height: ganttContainer.style.height,
          maxHeight: ganttContainer.style.maxHeight,
          position: ganttContainer.style.position,
          top: ganttContainer.style.top,
          left: ganttContainer.style.left,
          width: ganttContainer.style.width,
          zIndex: ganttContainer.style.zIndex
        }
        
        // 保存时间轴相关元素的原始样式
        const timelineArea = ganttContainer.querySelector('.timeline-area')
        const timelineContentWrapper = ganttContainer.querySelector('.timeline-content')
        const timelineHeader = ganttContainer.querySelector('.timeline-header-row')
        
        const originalTimelineStyles = {
          timelineArea: timelineArea ? {
            overflow: timelineArea.style.overflow,
            width: timelineArea.style.width,
            minWidth: timelineArea.style.minWidth
          } : null,
          timelineContent: timelineContentWrapper ? {
            width: timelineContentWrapper.style.width,
            minWidth: timelineContentWrapper.style.minWidth,
            overflow: timelineContentWrapper.style.overflow
          } : null,
          timelineHeader: timelineHeader ? {
            width: timelineHeader.style.width,
            minWidth: timelineHeader.style.minWidth,
            overflow: timelineHeader.style.overflow
          } : null
        }
        
        // 添加导出CSS类
        ganttContainer.classList.add('exporting')
        
        // 隐藏控制按钮
        const controlsElement = ganttContainer.querySelector('.gantt-controls')
        if (controlsElement) {
          controlsElement.style.display = 'none'
        }
        
        // 临时调整样式以显示全部内容
        ganttContainer.style.overflow = 'visible'
        ganttContainer.style.height = 'auto'
        ganttContainer.style.maxHeight = 'none'
        ganttContainer.style.position = 'relative'
        ganttContainer.style.top = 'auto'
        ganttContainer.style.left = 'auto'
        ganttContainer.style.width = 'auto'
        ganttContainer.style.zIndex = 'auto'
        
        // 等待DOM更新
        await nextTick()
        
        // 计算实际内容高度和宽度
        const taskListContent = ganttContainer.querySelector('.task-list')
        const timelineContent = ganttContainer.querySelector('.timeline-content-area')
        
        if (taskListContent && timelineContent) {
          const taskListHeight = taskListContent.scrollHeight
          const timelineHeight = timelineContent.scrollHeight
          const headerHeight = 50 // 头部高度
          const maxHeight = Math.max(taskListHeight, timelineHeight) + headerHeight + 20 // 额外20px边距
          
          // 设置容器高度为实际内容高度
          ganttContainer.style.height = maxHeight + 'px'
          
          // 确保时间轴区域显示完整内容
          const timelineArea = ganttContainer.querySelector('.timeline-area')
          if (timelineArea) {
            timelineArea.style.overflow = 'visible'
            timelineArea.style.width = 'auto'
            timelineArea.style.minWidth = 'auto'
          }
          
          // 确保时间轴内容区域显示完整
          const timelineContentWrapper = ganttContainer.querySelector('.timeline-content')
          if (timelineContentWrapper) {
            timelineContentWrapper.style.width = 'auto'
            timelineContentWrapper.style.minWidth = 'auto'
            timelineContentWrapper.style.overflow = 'visible'
          }
          
          // 确保时间轴头部显示完整
          if (timelineHeader) {
            timelineHeader.style.width = 'auto'
            timelineHeader.style.minWidth = 'auto'
            timelineHeader.style.overflow = 'visible'
          }
        }
        
        // 等待样式应用
        await nextTick()
        
        // 等待样式完全应用
        await nextTick()
        
        // 计算实际的总宽度（包括完整的时间轴）
        const actualWidth = taskListWidth.value + 6 + totalWidth.value // 任务列表宽度 + 分隔条宽度 + 时间轴总宽度
        
        // 使用html2canvas导出图片
        const canvas = await html2canvas(ganttContainer, {
          allowTaint: true,
          useCORS: true,
          scale: 2, // 提高图片质量
          backgroundColor: '#ffffff',
          width: actualWidth,
          height: ganttContainer.scrollHeight,
          scrollX: 0,
          scrollY: 0,
          windowWidth: actualWidth,
          windowHeight: ganttContainer.scrollHeight,
          logging: false,
          removeContainer: false
        })
        
        // 创建下载链接
        const link = document.createElement('a')
        link.download = `gantt-chart-${dayjs().format('YYYY-MM-DD-HH-mm-ss')}.png`
        link.href = canvas.toDataURL('image/png')
        link.click()
        
        // 移除导出CSS类
        ganttContainer.classList.remove('exporting')
        
        // 恢复控制按钮显示
        const controlsElementRestore = ganttContainer.querySelector('.gantt-controls')
        if (controlsElementRestore) {
          controlsElementRestore.style.display = ''
        }
        
        // 恢复原始样式
        Object.keys(originalStyles).forEach(key => {
          if (originalStyles[key] !== undefined) {
            ganttContainer.style[key] = originalStyles[key]
          }
        })
        
        // 恢复时间轴相关元素的原始样式
        if (originalTimelineStyles.timelineArea && timelineArea) {
          Object.keys(originalTimelineStyles.timelineArea).forEach(key => {
            if (originalTimelineStyles.timelineArea[key] !== undefined) {
              timelineArea.style[key] = originalTimelineStyles.timelineArea[key]
            }
          })
        }
        
        if (originalTimelineStyles.timelineContent && timelineContentWrapper) {
          Object.keys(originalTimelineStyles.timelineContent).forEach(key => {
            if (originalTimelineStyles.timelineContent[key] !== undefined) {
              timelineContentWrapper.style[key] = originalTimelineStyles.timelineContent[key]
            }
          })
        }
        
        if (originalTimelineStyles.timelineHeader && timelineHeader) {
          Object.keys(originalTimelineStyles.timelineHeader).forEach(key => {
            if (originalTimelineStyles.timelineHeader[key] !== undefined) {
              timelineHeader.style[key] = originalTimelineStyles.timelineHeader[key]
            }
          })
        }
        
      } catch (error) {
        console.error('导出图片失败:', error)
        // 这里可以添加错误提示
      } finally {
        isExporting.value = false
      }
    }
    
    // 处理排序变化
    const handleSortChange = (sortConfig) => {
      sortField.value = sortConfig.field
      sortDirection.value = sortConfig.direction
    }
    
    // 处理列配置变化
    const handleColumnsChange = (newColumns) => {
      // 通过emit将列配置变化传递给父组件
      emit('columns-change', newColumns)
    }
    
    // 计算过滤后的任务列表（用于时间轴显示）
    const filteredTasks = computed(() => {
      // 首先过滤任务（处理层级关系和收缩展开）
      const filtered = []
      
      // 安全检查
      if (!props.tasks || props.tasks.length === 0) {
        console.log('GanttChart - 没有任务数据')
        return filtered
      }
      
      const shouldShowTask = (task) => {
        // 顶级任务总是显示
        if (getTaskLevel(task) === 0) return true
        
        // 检查所有父级任务是否都展开
        let currentTask = task
        while (currentTask.parentId) {
          const parentTask = props.tasks.find(t => t.id === currentTask.parentId)
          if (!parentTask) {
            console.warn(`找不到父任务: ${currentTask.parentId} for task: ${task.id}`)
            return false
          }
          if (collapsedTasks.value.has(currentTask.parentId)) {
            console.log(`父任务 ${parentTask.name} 已收缩，隐藏子任务 ${task.name}`)
            return false
          }
          currentTask = parentTask
        }
        return true
      }
      
      // 递归函数：按层级顺序添加任务
      const addTasksInOrder = (parentId = null) => {
        // 找到所有以当前parentId为父级的任务
        const childTasks = props.tasks.filter(task => task.parentId === parentId)
        
        console.log(`查找parentId为 ${parentId} 的子任务:`, childTasks.map(t => `${t.name} (level: ${getTaskLevel(t)})`))
        
        childTasks.forEach(task => {
          const shouldShow = shouldShowTask(task)
          console.log(`任务 ${task.name} (level: ${getTaskLevel(task)}) 是否显示:`, shouldShow)
          
          if (shouldShow) {
            filtered.push(task)
            console.log(`添加任务: ${task.name} (level: ${getTaskLevel(task)})`)
            // 递归添加子任务
            addTasksInOrder(task.id)
          } else {
            console.log(`隐藏任务: ${task.name} (level: ${getTaskLevel(task)})`)
          }
        })
      }
      
      // 从顶级任务开始递归添加
      addTasksInOrder()
      
      console.log('GanttChart - 任务数量:', props.tasks.length)
      console.log('GanttChart - 过滤后任务数量:', filtered.length)
      console.log('GanttChart - 收缩状态:', Array.from(collapsedTasks.value))
      
      return filtered
    })
    
    return {
      timelineAreaRef,
      timelineStart,
      timelineEnd,
      filteredTasks,
      collapsedTasks,
      getSafeDayjs,
      getFormattedDate,
      getTaskLevel,
      tooltip,
      showTooltip,
      hideTooltip,
      handleTaskListScroll,
      handleTimelineScroll,
      selectTask,
      dragState,
      hasChildren,
      toggleTask,
      getTaskChildrenCount,
      viewType: currentViewType,
      isFullscreen,
      toggleFullscreen,
      taskListWidth,
      isResizing,
      startResize,
      isExporting,
      exportImage,
      handleSortChange,
      handleColumnsChange,
      handleTaskDragStart,
      handleTaskDragMove,
      handleTaskDragEnd,
      handleTooltipShow,
      handleTooltipHide,
      taskListScrollTop
    }
  }
}
</script>

<style scoped>
.gantt-chart {
  display: flex;
  flex-direction: column;
  height: 600px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.gantt-chart.fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 9999;
  border: none;
  border-radius: 0;
  background: white;
}

/* 导出时的样式调整 */
.gantt-chart.exporting {
  position: relative !important;
  top: auto !important;
  left: auto !important;
  width: auto !important;
  height: auto !important;
  z-index: auto !important;
  overflow: visible !important;
  max-height: none !important;
}

.gantt-chart.exporting .timeline-area {
  overflow: visible !important;
  width: auto !important;
  min-width: auto !important;
}

.gantt-chart.exporting .timeline-content {
  width: auto !important;
  min-width: auto !important;
  overflow: visible !important;
}

.gantt-chart.exporting .timeline-header-row {
  width: auto !important;
  min-width: auto !important;
  overflow: visible !important;
}

.gantt-chart.exporting .gantt-controls {
  display: none !important;
}

.gantt-header {
  display: flex;
  background: #fafafa;
  border-bottom: 1px solid #d9d9d9;
  height: 50px;
  align-items: center;
  position: relative;
}

.gantt-controls {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
}

.task-list-header {
  padding: 0 16px;
  font-weight: 500;
  font-size: 14px;
  border-right: 1px solid #d9d9d9;
  height: 100%;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  flex-shrink: 0;
}

.timeline-header {
  flex: 1;
  padding: 0 16px;
  font-weight: 500;
  font-size: 14px;
  height: 100%;
  display: flex;
  align-items: center;
  box-sizing: border-box;
}

.gantt-body {
  display: flex;
  flex: 1;
  overflow: hidden;
}



.resize-handle-vertical {
  width: 6px;
  background: #f0f0f0;
  cursor: col-resize;
  position: relative;
  flex-shrink: 0;
  transition: background-color 0.2s ease;
}

.resize-handle-vertical:hover {
  background: #d0d0d0;
}

.resize-handle-vertical.resizing {
  background: #409EFF;
}

.resize-handle-vertical::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 2px;
  height: 20px;
  background: #ccc;
  border-radius: 1px;
}

.resize-handle-vertical:hover::after {
  background: #999;
}

.resize-handle-vertical.resizing::after {
  background: white;
}



.timeline-area {
  flex: 1;
  overflow-x: auto;
  overflow-y: hidden;
  position: relative;
  min-width: 0;
}

.timeline-content {
  position: relative;
}

.timeline-header-row {
  display: flex;
  background: #f0f0f0;
  border-bottom: 1px solid #d9d9d9;
  position: sticky;
  top: 0;
  z-index: 100;
  height: 50px;
  align-items: center;
  box-sizing: border-box;
  padding: 0;
}

.timeline-unit-header {
  text-align: center;
  padding: 4px 0;
  font-size: 12px;
  font-weight: 500;
  border-right: 1px solid #d9d9d9;
  flex-shrink: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.unit-label {
  font-weight: 600;
  margin-bottom: 2px;
}

.unit-sub-label {
  font-size: 10px;
  color: #666;
  font-weight: normal;
}

.timeline-content-area {
  position: relative;
  background: repeating-linear-gradient(
    90deg,
    transparent,
    transparent calc(var(--unit-width, 100px) - 1px),
    #f0f0f0 calc(var(--unit-width, 100px) - 1px),
    #f0f0f0 var(--unit-width, 100px)
  );
  border-right: 1px solid #d9d9d9;
}

.dependency-lines {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 40;
}

.task-bar-container {
  position: absolute;
  height: 50px;
  width: 100%;
}

.task-bar {
  position: absolute;
  height: 30px;
  border-radius: 4px;
  cursor: grab;
  display: flex;
  align-items: center;
  padding: 0 8px;
  color: white;
  font-size: 12px;
  font-weight: 500;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.2s;
  user-select: none;
  top: 10px;
  overflow: hidden;
}

.task-bar:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  transform: translateY(-1px);
}

.task-bar {
  position: relative;
}

.task-bar::after {
  content: "双击编辑";
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 10px;
  color: rgba(255, 255, 255, 0.8);
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none;
  z-index: 5;
}

.task-bar:hover::after {
  opacity: 1;
}

.task-bar.dragging {
  cursor: grabbing;
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
  transform: translateY(-2px);
}

.task-bar-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  z-index: 1;
  position: relative;
}

.task-name {
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.task-progress {
  font-size: 10px;
  margin-left: 8px;
}

.task-progress-container {
  position: absolute;
  top: 0;
  left: 8px;
  right: 8px;
  height: 100%;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  pointer-events: none;
  box-sizing: border-box;
  overflow: hidden;
}

.task-progress-fill {
  height: 100%;
  background: rgba(255, 255, 255, 0.4);
  border-radius: 4px;
  pointer-events: none;
  box-sizing: border-box;
  transition: width 0.3s ease;
}

.today-line {
  position: absolute;
  top: 0;
  width: 2px;
  background: #f56c6c;
  z-index: 100;
}

.time-range-indicator {
  position: absolute;
  top: 0;
  background: rgba(64, 158, 255, 0.1);
  border-left: 2px solid #409EFF;
  border-right: 2px solid #409EFF;
  pointer-events: none;
  z-index: 50;
}

.resize-handle {
  position: absolute;
  width: 10px;
  height: 100%;
  top: 0;
  cursor: col-resize;
  z-index: 10;
}

.resize-start {
  left: -5px;
}

.resize-end {
  right: -5px; /* 恢复原来的定位方式 */
}

/* 任务名称内容样式 */
.task-name-content {
  display: flex;
  align-items: center;
  width: 100%;
}

/* 展开/收缩按钮样式 */
.expand-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-right: 6px;
  cursor: pointer;
  border-radius: 3px;
  transition: all 0.2s ease;
  color: #666;
  flex-shrink: 0;
}

.expand-toggle:hover {
  background-color: #e6f7ff;
  color: #409EFF;
  transform: scale(1.1);
}

.expand-toggle.expanded {
  color: #409EFF;
}

.expand-toggle.expanded:hover {
  background-color: #d1e7ff;
}

.expand-icon {
  width: 18px;
  height: 18px;
  transition: transform 0.2s ease;
}

.expand-toggle.expanded .expand-icon {
  transform: rotate(90deg);
}

/* 占位符样式 */
.expand-placeholder {
  width: 20px;
  height: 20px;
  margin-right: 6px;
  display: inline-block;
  flex-shrink: 0;
}


</style> 